<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>From templates...</title>
    <meta name="description" content="Redirects you to the Google Drive templates gallery. The trick is that we need to know if the user is a Google Apps user in which case we rediret him to a special URL. To know if the user is a Google APps user we use Google's UserInfo API." />
    <!--[if lt IE 8]>  
      <script src="json2.js"></script>  
    <![endif]-->  
    <script type="text/javascript">
      // Fix for IE's missing console.log().
      if (!window.console) console = {log: function() {}};

      // The app's client ID.
      var CLIENT_ID = "381353196765.apps.googleusercontent.com";  
      
      /**
       * Checks if the user is authorized and if not triggers the OAuth flow.
       */
      function init() {
        // Check if we have an access token in the hash portion of the URL.
        if (!hasGoneTroughAuth()) {
          console.log("No access token yet.");
          // No Access Token so we make the users go through an OAuth flow.
          var userId = getUserIdFromStateParam();
          console.log("Found user ID: " + userId);
          // If the user ID was not found it means that the user is not comming
          // from Google Drive so we install the app.
          var scopes = userId ?
              "email" : "email https://www.googleapis.com/auth/drive.install";
          // Redirect to the auth page using the OAuth 2.0 client side flow.
          var authFlowUrl = createOAuthClientFlowUrl(CLIENT_ID, scopes, userId);
          console.log("Redirecting user to: " + authFlowUrl);
          window.location.href = authFlowUrl;
        }
        // Periodically check if the user is authorized.
        periodicCheckAuth();
      }
      
      /**
       * Periodically checks if the user is authorized and if it is query the
       * UserInfo API.
       */
      function periodicCheckAuth() {
        console.log("Checking auth.");
        // We have an Access Token which means the user has authorized the app.
        if (hasGoneTroughAuth()) {
          // First we extract the access token from the hash portion of the URL.
          var accessToken = parseHashParameters().access_token;
          console.log("Found an access token: " + accessToken);
          // Now we can call the UserInfo API using the token.
          callUserInfoApiUsingJsonp(accessToken)
        } else {
          // Checking again every 0.1s because in some cases Chrome will not
          // reload the page but will only change the hash.
          console.log("Checking auth again...");
          window.setTimeout(periodicCheckAuth, 100);
        }
      }
      
      /**
       * Tests if the current user has gone Through auth already.
       *
       * @return{boolean} True if the user has alrady gone through auth.
       */
      function hasGoneTroughAuth() {
        return window.location.hash.indexOf("access_token=") > -1
            || window.location.hash.indexOf("error=") > -1;
      }
      
      /**
       * When a user gets redirect from Google Drive to an app using the Create
       * menu Google Drive will pass the ID of the user in the State parameter
       * which will be a serialized JSON object. This functions extracts and
       * returns the User ID from such state parameter.
       *
       * @return{String} The ID of the user or undefined if it wasn't found.
       */
      function getUserIdFromStateParam() {
        try {
          var state = decodeURIComponent(location.search.split("state=")[1]);
          var stateObj = JSON.parse(state);
          // Hurray we found the User's ID.
          return stateObj.userId;
        } catch(e) {
          return undefined;
        }
      }
      
      /**
       * Returns the URL that initiates the OAuth Client side flow using the
       * current URL without the URL parmaters and the hash portion as the
       * redirect URI.
       *
       * @param{String} clientId The Client ID of the application.
       * @param{String} scopes The space delimited list of scopes to authorize.
       * @param{String} userId The ID of the user. Can be null or undefined.
       * @return{String} The URL that initiates the OAuth flow.
       */
      function createOAuthClientFlowUrl(clientId, scopes, userId) {
         return "https://accounts.google.com/o/oauth2/auth?"
           + "redirect_uri=" + encodeURIComponent(location.protocol + '//'
                                   + location.host + location.pathname)
           + "&response_type=token"
           + "&client_id=" + encodeURIComponent(clientId)
           + "&scope=" + encodeURIComponent(scopes)
           + (userId ? "&user_id=" + encodeURIComponent(userId) : "");
      }
      
      /**
       * Returns the parameters located in the Hash portion of the URL.
       *
       * @return{Object} The key/value map of the current Hash parameters.
       */
       function parseHashParameters() {
        var hashParamsObject = new Object();
        var hashParamList = window.location.hash.split("&");
        for (index in hashParamList) {
          var hashParam = hashParamList[index].split("=");
          // remove heading '#' if it exists.
          hashParam[0] = hashParam[0].indexOf("#") == 0 ?
              hashParam[0].substr(1) : hashParam[0];
          hashParamsObject[hashParam[0]] = hashParam[1];
        }
        return hashParamsObject;
      }
      
      /**
       * Perform the request to the UserInfo API using JSON-P. When the request
       * finishes the function 'redirectsToCorrectTemplateGalleryUrl' is called.
       *
       * @param{String} accessToken An OAuth 2.0 Access Token authorized for the
       *                            scope 'email'.
       */
      function callUserInfoApiUsingJsonp(accessToken){
        console.log("Calling the UserInfo API using JSON-P");
        var head = document.getElementsByTagName('head')[0];
        var script= document.createElement('script');
        script.type= 'text/javascript';
        script.src= "https://www.googleapis.com/oauth2/v2/userinfo?"
            + "callback=redirectsToCorrectTemplateGalleryUrl"
            + "&access_token=" + accessToken;
        head.appendChild(script);
      }
        
      /**
       * Redirects the user to the correct Google Drive Gallery URL.
       *
       * @param{Object} resp The response object frpom the UserInfo API.
       */
      function redirectsToCorrectTemplateGalleryUrl(resp) {
        console.log("Received response from the UserInfo API: " + resp);
        var appsDomain = resp.hd;
        if (appsDomain) {
          console.log("Redirecting to the Google Apps Gallery URL.");
          window.location.href = "https://drive.google.com/a/"
              + encodeURIComponent(appsDomain) + "/templates";
        } else {
          console.log("Redirecting to the regular Gallery URL.");
          window.location.href = "https://drive.google.com/templates";
        }
      }
    </script>
  </head>
  <body style="width: 100%; height: 100%;" onload="init()">
    <table style="width: 100%; height: 100%; height: 300px;">
      <tr>
        <td style="vertical-align: bottom; text-align: center;">
          <img style="margin-bottom: 20px" width="220" height="19" title="Loading..." alt="Loading..."
               src="" />
        </td>
      </tr><tr>
        <td style="vertical-align: top; text-align: center; font-family: sans-serif,arial; font-size: 20px;">
          Loading the Google Docs Template Gallery...
        </td>
      </tr>
    </table>
    <script type="text/javascript">
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-25993200-3']);
      _gaq.push(['_trackPageview']);
    
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
    </script>
  </body>
</html>
